package com.hwadee.property.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hwadee.property.dto.ChargeDetailPersonal;
import com.hwadee.property.mapper.ChargeDetailMapper;
import com.hwadee.property.pojo.*;
import com.hwadee.property.service.*;
import com.hwadee.property.dto.PageResult;
import com.hwadee.property.util.BusinessException;
import com.hwadee.property.util.DateUtil;
import com.hwadee.property.util.ErrorCodes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChargeDetailServiceImpl extends ServiceImpl<ChargeDetailMapper, ChargeDetail> implements IChargeDetailService {

    @Autowired
    private ChargeDetailMapper chargeDetailMapper;

    @Autowired
    private ICommunityService communityService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IChargeItemService chargeItemService;

    @Autowired
    private IBuildingService buildingService;

    @Autowired
    private IHouseService houseService;

    @Override
    public PageResult<ChargeDetail> getPage(int current, int size, Long ownerId, Long communityId,
                                            Long houseId, Long chargeId, Long propertyStaffId, Integer feeMonth, int paymentStatus) {
        // 校验分页参数
        if (current < 1 || size < 1) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "分页参数必须大于0");
        }

        int offset = (current - 1) * size;
        int total = chargeDetailMapper.countChargeDetails(ownerId, communityId, houseId, chargeId, propertyStaffId, feeMonth, paymentStatus);
        List<ChargeDetail> records = (total > 0) ? chargeDetailMapper.getChargeDetails(ownerId, communityId, houseId, chargeId, propertyStaffId, feeMonth, paymentStatus, size, offset) : Collections.emptyList();

        return new PageResult<>(total, current, size, records);
    }

    @Override
    public List<ChargeDetailPersonal> listByOwnerId(Long ownerId) {
        // 校验业主ID
        if (ownerId == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "业主ID不能为空");
        }

        List<ChargeDetail> chargeDetails = this.list(new LambdaQueryWrapper<ChargeDetail>().eq(ChargeDetail::getOwnerId, ownerId));
        List<ChargeDetailPersonal> chargeDetailPersonalList = new ArrayList<>();

        for (ChargeDetail i : chargeDetails) {
            ChargeDetailPersonal chargeDetailPersonal = new ChargeDetailPersonal();
            chargeDetailPersonal.setId(i.getId());
            chargeDetailPersonal.setChargeName(chargeItemService.getById(i.getChargeId()).getChargeName());
            String houseName = communityService.getById(i.getCommunityId()).getCommunityName() + "小区" +
                    buildingService.getById(houseService.getById(i.getHouseId()).getBuildingId()).getBuildingNumber() + "栋" +
                    buildingService.getById(houseService.getById(i.getHouseId()).getBuildingId()).getBuildingUnit() + "单元" +
                    houseService.getById(i.getHouseId()).getFloor().toString() + "0" + houseService.getById(i.getHouseId()).getRoomNumber() + "房";
            chargeDetailPersonal.setHouseName(houseName);
            chargeDetailPersonal.setMonth(i.getFeeMonth());
            chargeDetailPersonal.setPropertyStaff(userService.getById(i.getPropertyStaffId()).getName());
            chargeDetailPersonal.setDosage(Math.round(i.getDosage() * 10) / 10.0); // 一位小数
            chargeDetailPersonal.setAmount(Math.round(i.getAmount() * 100) / 100.0); // 两位小数
            chargeDetailPersonal.setStatus(i.getPaymentStatus() == 1 ? "已缴费" : "未缴费");
            chargeDetailPersonal.setCreateDate(i.getCreateDate());
            chargeDetailPersonal.setPaymentDate(i.getPaymentDate());
            chargeDetailPersonalList.add(chargeDetailPersonal);
        }

        // 根据缴费状态排序，未缴费的排在前面
        chargeDetailPersonalList.sort((o1, o2) -> {
            int status1 = o1.getStatus().equals("未缴费") ? 0 : 1;
            int status2 = o2.getStatus().equals("未缴费") ? 0 : 1;
            return Integer.compare(status1, status2);
        });

        return chargeDetailPersonalList;
    }


    @Override
    public boolean updatePaymentStatus(Long id, int paymentStatus) {
        // 校验收费明细ID
        if (id == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "收费明细ID不能为空");
        }
        ChargeDetail chargeDetail = new ChargeDetail();
        chargeDetail.setId(id);
        chargeDetail.setPaymentStatus(paymentStatus);
        if (paymentStatus == 1) chargeDetail.setPaymentDate(DateUtil.dateToString(new Date()));
        return this.updateById(chargeDetail);
    }

    @Override
    public Map<Integer, Integer> countPaymentStatusByCommunity(Long communityId) {
        // 校验小区ID
        if (communityId == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "小区ID不能为空");
        }
        List<ChargeDetail> chargeDetails = this.list(new LambdaQueryWrapper<ChargeDetail>()
                .eq(ChargeDetail::getCommunityId, communityId));
        return chargeDetails.stream()
                .collect(Collectors.groupingBy(ChargeDetail::getPaymentStatus, Collectors.summingInt(e -> 1)));
    }

    @Override
    public boolean addChargeDetail(ChargeDetail chargeDetail) {
        if (chargeDetail == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "缴费详情不能为空");
        }

        // 校验房屋 ID
        if (chargeDetail.getHouseId() == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "房屋ID不能为空");
        }

        // 查询房屋信息
        House house = houseService.getById(chargeDetail.getHouseId());
        if (house == null) {
            throw new BusinessException(ErrorCodes.NOT_FOUND, "房屋不存在");
        }

        // 查询楼栋信息
        Building building = buildingService.getById(house.getBuildingId());
        if (building == null) {
            throw new BusinessException(ErrorCodes.NOT_FOUND, "楼栋不存在");
        }

        // 设定小区 ID 和业主 ID
        chargeDetail.setCommunityId(building.getCommunityId());
        chargeDetail.setOwnerId(house.getOwnerId());

        // 获取当前月份
        int currentMonth = LocalDateTime.now().getMonthValue();
        chargeDetail.setFeeMonth(currentMonth);
        chargeDetail.setPaymentStatus(0);
        chargeDetail.setCreateDate(DateUtil.dateToString(new Date()));

        // 生成订单编号
        chargeDetail.setTraceNo(generateRandomTraceNo());
        chargeDetail.setAlipayTraceNo(generateRandomTraceNo());

        return this.save(chargeDetail);
    }


    @Override
    public List<ChargeDetail> addChargeDetailByProperty(Long userId, Integer month) {
        Community community = communityService.getById(userService.getById(userId).getCommunityId());
        ChargeItem waterCharge = chargeItemService.getUnitFeeByCommunityID(community.getId(), "水费");
        ChargeItem electricCharge = chargeItemService.getUnitFeeByCommunityID(community.getId(), "电费");
        ChargeItem gasCharge = chargeItemService.getUnitFeeByCommunityID(community.getId(), "燃气费");

        List<House> houses = houseService.listByCommunityId(community.getId());
        List<ChargeDetail> newChargeDetailList = new ArrayList<>();

        for (House i : houses){
            ChargeDetail waterChargeDetail = generateChargeDetail(community, waterCharge, i, userId, month);
            ChargeDetail ElectricChargeDetail = generateChargeDetail(community, electricCharge, i, userId, month);
            ChargeDetail GaschargeDetail = generateChargeDetail(community, gasCharge, i, userId, month);
            newChargeDetailList.add(waterChargeDetail);
            newChargeDetailList.add(ElectricChargeDetail);
            newChargeDetailList.add(GaschargeDetail);
        }
        return newChargeDetailList;
    }

    @Override
    public List<String> listUnPayOwnerName(Long communityId) {
        // 校验小区ID
        if (communityId == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "小区ID不能为空");
        }

        // 查询未支付的 ChargeDetail 列表
        List<ChargeDetail> chargeDetails = this.list(new LambdaQueryWrapper<ChargeDetail>()
                .eq(ChargeDetail::getCommunityId, communityId)
                .eq(ChargeDetail::getPaymentStatus, 0));

        // 提取 Name 属性并去重
        Set<String> nameSet = new LinkedHashSet<>(); // 使用 LinkedHashSet 保持插入顺序
        if (!chargeDetails.isEmpty()){
            for (ChargeDetail chargeDetail : chargeDetails) {
                String name = null;
                if (chargeDetail.getOwnerId()!=null) name = userService.getById(chargeDetail.getOwnerId()).getName();
                if (name != null) {
                    nameSet.add(name);
                }
            }
        }

        // 将 Set 转换为 List 返回
        return new ArrayList<>(nameSet);
    }



    private ChargeDetail generateChargeDetail(Community community, ChargeItem chargeItem, House house, Long userId, int month) {
        try {
            ChargeDetail chargeDetail = new ChargeDetail();
            chargeDetail.setHouseId(house.getId());
            chargeDetail.setChargeId(chargeItem.getId());
            chargeDetail.setPropertyStaffId(userId);
            chargeDetail.setOwnerId(house.getOwnerId());
            chargeDetail.setCommunityId(community.getId());
            double dosage = getDosage();
            dosage = Math.round(dosage * 100.0) / 100.0; // 保留两位小数
            chargeDetail.setDosage(dosage);
            double amount = dosage * chargeItem.getAmount();
            amount = Math.round(amount * 100.0) / 100.0; // 保留两位小数
            chargeDetail.setAmount(amount);
            chargeDetail.setCreateDate(DateUtil.dateToString(new Date()));
            chargeDetail.setFeeMonth(month);
            chargeDetail.setPaymentStatus(0);
            chargeDetail.setTraceNo(generateRandomTraceNo());
            addChargeDetail(chargeDetail);
            return chargeDetail;
        } catch (Exception e) {
            throw new RuntimeException("Error occurred while generating charge detail: " + e.getMessage());
        }
    }


    /**
     * 模拟生成用量，实际可能来源于具体器械计数
     * @return 用量的虚拟值
     */
    private Double getDosage() {
        // 生成一个范围在[0.0, 1.0)的随机数
        double randomValue = Math.random();
        // 将随机数缩放到[0, 20)范围，然后平移10，最终范围为[10, 30)
        return 10 + (randomValue * 20);
    }


    /**
     * 生成随机订单号和支付宝交易凭证号的方法
     * @return 随机编号
     */
    private String generateRandomTraceNo() {
        return UUID.randomUUID().toString().replace("-", ""); // 使用UUID生成随机字符串并去掉短横线(32位)
    }

    public ChargeDetail getByTradeNo(String tradeNo) {
        if (tradeNo == null || tradeNo.trim().isEmpty()) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "交易号不能为空");
        }
        return chargeDetailMapper.getByTradeNo(tradeNo);
    }
}
